package cn.com.pansky.action.bank;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.vsame.url2sql.sql.Model;

import org.apache.commons.lang3.StringUtils;

import cn.com.pansky.action.logs.Log;
import cn.com.pansky.payment.PayConf;
import cn.com.pansky.service.OrderBackWriteService;
import cn.com.pansky.service.OrderService;
import cn.com.pansky.util.AppUtils;
import cn.com.pansky.util.DateUtil;
import cn.com.pansky.util.EncryptionUtils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;

/**
 * Servlet implementation class payjh
 */
public class Payment extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Log log = new Log();
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Payment() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//日志记录start
//		String CA001 = (String) request.getSession().getAttribute("CA001");
//		Model m = (Model) request.getSession().getAttribute("user");
//		String AA001 = m.getString("AA001");
//		String AF001 = log.start(CA001, AA001, "JF");
//		System.out.println("缴费日志start："+AF001);
//		request.getSession().setAttribute("AF001", AF001);
		
		//缴费金额是0元
//		if ("0".equals(request.getParameter("orderAmount"))) {
//			System.out.println(request.toString());
//			OrderBackWriteService orderBackWriteService = new OrderBackWriteService(); // 银行支付成功，系统数据回填接口
//			Map<String, String> map = new HashMap<String, String>();
//			map.put("bankType", request.getParameter("BAB502")); // 银行类别
//			map.put("AcqSsn", "123456"); // 银行缴费流水号
//			map.put("TranAmt", "0"); // 缴费金额
//			map.put("TermSsn", request.getParameter("orderNumber")); // 订单号
//			Model alias = (Model) request.getSession().getAttribute("user"); // 用户ID
//			map.put("AAE011", alias.getString("AA001"));
//			map.put("AAC002", request.getSession().getAttribute("orderWriteCA006").toString()); // 身份证号
//			map.put("AAE010", "999999");
//			JSONObject object = orderBackWriteService.orderBackWrite(map); // 回填订单信息
//			System.out.println(object);
//			return;
//		}
		
		String flag = request.getParameter("flag");
		
		if ("ZG".equals(flag)) {
			JHPayment_ZG(request, response, flag);
		}
		// 1：web端支付，2：app支付
		String payType = request.getParameter("payType");
		if(payType == null || payType.equals("")) {
			payType = "2";
		}
		String bab502 = request.getParameter("BAB502");
		if(bab502.equals("YC")) {
			// 邮储支付
			response.sendRedirect("psbcPayment?appId=6103_web&sig=xxx&orderAmount="+request.getParameter("orderAmount")+"&orderNumber="+request.getParameter("orderNumber")+"&payType="+payType);// 邮储支付接口
		} else if(bab502.equals("NH")) {
			// 农行支付
			response.sendRedirect("abcPayment?appId=6103_web&sig=xxx&orderAmount="+request.getParameter("orderAmount")+"&orderNumber="+request.getParameter("orderNumber")+"&payType="+payType);// 农行支付接口
		} else if(bab502.equals("WX")) {
			//微信支付
			WXPayment(request, response);
		} else {
			// 建行支付
			JHPayment(request, response);
		}
		
	}
	
	/**
	 * 微信支付
	 * @param request
	 * @param response
	 */
	public void WXPayment(HttpServletRequest request,
			HttpServletResponse response) {
		//请求参数模板：
		//		<xml>
		//		   <appid>wx2421b1c4370ec43b</appid>
		//		   <attach>支付测试</attach>
		//		   <body>APP支付测试</body>
		//		   <mch_id>10000100</mch_id>
		//		   <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
		//		   <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
		//		   <out_trade_no>1415659990</out_trade_no>
		//		   <spbill_create_ip>14.23.150.211</spbill_create_ip>
		//		   <total_fee>1</total_fee>
		//		   <trade_type>APP</trade_type>
		//		   <sign>0CB01533B8C1EF103065174F50BCA001</sign>
		//		</xml>
		
		try {
			URL url = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");
	        URLConnection con = url.openConnection();
	        con.setDoOutput(true);
	        con.setRequestProperty("Pragma:", "no-cache");
	        con.setRequestProperty("Cache-Control", "no-cache");
	        con.setRequestProperty("Content-Type", "text/xml");
	
	        OutputStreamWriter out = new OutputStreamWriter(con
	                .getOutputStream());    
	        Map<String, String[]> paramsMap = new HashMap<String, String[]>();
	        StringBuilder sb = new StringBuilder();
	        sb.append("<xml>");
	        sb.append("    <appid>wx2421b1c4370ec43b</appid>");		//应用ID
	        paramsMap.put("appid", new String[] { "wx2421b1c4370ec43b" });
	        sb.append("    <attach>test</attach>");				//附加数据
	        paramsMap.put("attach", new String[] { "test" });
	        sb.append("    <body>test</body>");				//商品描述
	        paramsMap.put("body", new String[] { "test" });
	        sb.append("    <mch_id>10000100</mch_id>");				//商户号
	        paramsMap.put("mch_id", new String[] { "10000100" });
	        sb.append("    <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>");		//随机字符串
	        paramsMap.put("nonce_str", new String[] { "1add1a30ac87aa2db72f57a2375d8fec" });
	        sb.append("    <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>");		//通知地址
	        paramsMap.put("notify_url", new String[] { "http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php" });
	        sb.append("    <out_trade_no>123456</out_trade_no>");			//商户订单号
	        paramsMap.put("out_trade_no", new String[] { "123456" });
	        sb.append("    <spbill_create_ip>10.189.139.32</spbill_create_ip>");		//终端IP
	        paramsMap.put("spbill_create_ip", new String[] { "10.189.139.32" });
	        //将金额转为分
	        String orderNum = Double.parseDouble(request.getParameter("orderNumber"))*100 + "";
	        String money = "";
	        if (orderNum.contains(".")) {
				money = orderNum.split(".")[0];
			} else {
				money = orderNum;
			}
	        sb.append("    <total_fee>"+money+"</total_fee>");		//总金额
	        paramsMap.put("total_fee", new String[] { money });
	        sb.append("    <trade_type>APP</trade_type>");		//支付类型
	        paramsMap.put("trade_type", new String[] { "APP" });
	        String sign = EncryptionUtils.makeSignature(paramsMap, "pansky");
	        sb.append("    <sign>"+sign+"</sign>");		//签名
	        sb.append("</xml>");
	        String xmlInfo = sb.toString();
	        out.write(new String(xmlInfo.getBytes("ISO-8859-1")));
	        out.flush();
	        out.close();
	        BufferedReader br = new BufferedReader(new InputStreamReader(con
	                .getInputStream()));
	        String line = "";
	        String result = "";
	        for (line = br.readLine(); line != null; line = br.readLine()) {
	            result = result + line;
	        }
	        String return_code = result.split("<return_code>")[1].split("</return_code>")[0];
	        System.out.println(result);
	        boolean boo = return_code.contains("SUCCESS");
	        if (boo) {
				//下单成功
	        	//返回模板;
	    		//		<xml>
	    		//		   <return_code><![CDATA[SUCCESS]]></return_code>
	    		//		   <return_msg><![CDATA[OK]]></return_msg>
	    		//		   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
	    		//		   <mch_id><![CDATA[10000100]]></mch_id>
	    		//		   <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
	    		//		   <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
	    		//		   <result_code><![CDATA[SUCCESS]]></result_code>
	    		//		   <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
	    		//		   <trade_type><![CDATA[APP]]></trade_type>
	    		//		</xml>
	        	String appid = result.split("<appid>")[1].split("</appid>")[0].split("CDATA")[1];
	        	appid = appid.substring(1, appid.length()-3);
	        	String mch_id = result.split("<mch_id>")[1].split("</mch_id>")[0].split("CDATA")[1];
	        	mch_id = mch_id.substring(1,mch_id.length()-3);
	        	String nonce_str = result.split("<nonce_str>")[1].split("</nonce_str>")[0].split("CDATA")[1];
	        	nonce_str = nonce_str.substring(1,nonce_str.length()-3);
	        	String sign_ = result.split("<sign>")[1].split("</sign>")[0].split("CDATA")[1];
	        	sign_ = sign_.substring(1,sign_.length()-3);
	        	String result_code = result.split("<result_code>")[1].split("</result_code>")[0].split("CDATA")[1];
	        	result_code = result_code.substring(1,result_code.length()-3);
	        	String prepay_id = "";
	        	String trade_type = "";
	        	if ("SUCCESS".equals(result_code)) {
	        		prepay_id = result.split("<prepay_id>")[1].split("</prepay_id>")[0].split("CDATA")[1];
	        		prepay_id = prepay_id.substring(1,prepay_id.length()-3);
	        		trade_type = result.split("<trade_type>")[1].split("</trade_type>")[0].split("CDATA")[1];
	        		trade_type = trade_type.substring(1,trade_type.length()-3);
				}
	        	//TODO 将微信接口返回的数据发送给app
			} else {
				//下单失败
				System.out.println(result);
				//TODO 告知app下单失败
			}
		} catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
		
	}
	
	/**
	 * 建行支付
	 * @param request
	 * @param response
	 * @throws UnsupportedEncodingException
	 */
	private void JHPayment(HttpServletRequest request,
			HttpServletResponse response) throws UnsupportedEncodingException {
		// 将支付金额分转元
		BigDecimal orderAmount = new BigDecimal(request.getParameter("orderAmount"));
		orderAmount = orderAmount.multiply(new BigDecimal(100));
		// 获取请求
		// 定义接口数据集合
		Map<String, String> paramMap = Maps.newHashMap();
		

		paramMap.put("defaultBankNumber", "105");
		paramMap.put("agentAmount", PayConf.MERID+"00000="+orderAmount.intValue()); // 网关
		paramMap.put("charset", "UTF-8");
		paramMap.put("merId", PayConf.MERID); // 商户编号
		paramMap.put("orderTime", DateUtil.currentTime()); // 订单时间
		paramMap.put("orderCurrency", PayConf.ORDERCURRENCY);
		paramMap.put("customerIp", request.getRemoteHost());
		paramMap.put("version", PayConf.PAY_VERSION); // 支付版本
		paramMap.put("signMethod", PayConf.SIGNMETHOD);
		paramMap.put("transType", PayConf.PAY_TRANSTYPE);
		paramMap.put("orderAmount", orderAmount.intValue()+""); // 订单金额 //
		paramMap.put("orderNumber", request.getParameter("orderNumber")); // 商户订单号
		paramMap.put("payType", "B2C");
		paramMap.put("terType", "00"); // 网关

		paramMap.put("backEndUrl", PayConf.backEndUrl); //  通知url
		paramMap.put("frontEndUrl", PayConf.frontEndUrl); // 返回url
	
		paramMap.put("merReserved1", new String(request.getParameter("CA003").getBytes("ISO8859-1"), "UTF-8")); //商户保留字，存参保人姓名
		Model user = (Model) request.getSession().getAttribute("user");
		paramMap.put("merReserved2", user.getString("AA001")); //商户保留字，存用户ID
		paramMap.put("merReserved3", (String)request.getSession().getAttribute("orderWriteCA006")); //商户保留字，存用户ID
		paramMap.put("gateWay", PayConf.PAY_VERSION); // 网关
		
		// 定义接口参数
        String[] paramKeys = new String[]{"version", "charset", "signMethod", "payType", "transType", //
                "merId", "backEndUrl", "frontEndUrl", "orderTime", "orderNumber", "orderAmount", "orderCurrency", //
                "defaultBankNumber", "customerIp", "merReserved1", "merReserved2", "merReserved3", //
                "gateWay", "terType", "agentAmount", "orderDesc", "payPerson", "idType", "certifId", "openid"};
		Map<String, String> paramMap22 = Maps.newHashMap();
		
        for (String key : paramKeys) {
        	paramMap22.put(key, paramMap.get(key));
        }
        
        paramMap22 = Maps.filterEntries(paramMap22, new Predicate<Map.Entry<String, String>>() {
            @Override
            public boolean apply(Map.Entry<String, String> entry) {
                return StringUtils.isNotBlank(entry.getValue());
            }
        });

        //生成签名
        String sign = AppUtils.signBeforePost(paramMap22, PayConf.SIGNKEY, PayConf.CHARSET);
//        String sign = AppUtils.signBeforePost(paramMap, reqMap.get("signKey"), charset);
        System.out.println("向清算平台发送支付请求:" + paramMap22.toString());
        System.out.println("原始签名：" + sign);

        //构造请求数据表单, 过滤掉为空的值，签名时也过滤
        StringBuilder builder = new StringBuilder();
        builder.append("\r\n<script language=\"javascript\">window.onload=function(){document.payform.submit();}</script>\r\n");
        builder.append("\r\n<form id='payform' name='payform' action='" + PayConf.JSPT_PAY_URL + "' method='POST'>\r\n");
        for (String item : paramKeys) {
            String value = paramMap22.get(item);
            if (StringUtils.isNotBlank(value)) {
                builder.append("\t<input type='hidden' name='" + item + "' value='" + paramMap22.get(item) + "' />\r\n");
            }
        }
        builder.append("\t<input type='hidden' name='sign' value='" + sign + "' />\r\n");
        builder.append("</form>\r\n");


        response.setContentType("text/html;charset=" + PayConf.CHARSET);
        response.setCharacterEncoding(PayConf.CHARSET);
        try {
        	response.getWriter().write(builder.toString().replace('\'', '"'));
        } catch (IOException e) {
            System.out.println("支付失败");
        }
	}
	
	
	private void JHPayment_ZG(HttpServletRequest request,
			HttpServletResponse response, String flag) throws UnsupportedEncodingException {
		// 将支付金额分转元
		BigDecimal orderAmount = new BigDecimal(request.getParameter("orderAmount"));
		orderAmount = orderAmount.multiply(new BigDecimal(100));
		// 获取请求
		// 定义接口数据集合
		Map<String, String> paramMap = Maps.newHashMap();
		

		paramMap.put("defaultBankNumber", "105");
		paramMap.put("agentAmount", PayConf.MERID_ZG+"00000="+orderAmount.intValue()); // 网关
		paramMap.put("charset", "UTF-8");
		paramMap.put("merId", PayConf.MERID_ZG); // 商户编号
		paramMap.put("orderTime", DateUtil.currentTime()); // 订单时间
		paramMap.put("orderCurrency", PayConf.ORDERCURRENCY);
		paramMap.put("customerIp", request.getRemoteHost());
		paramMap.put("version", PayConf.PAY_VERSION); // 支付版本
		paramMap.put("signMethod", PayConf.SIGNMETHOD);
		paramMap.put("transType", PayConf.PAY_TRANSTYPE);
		paramMap.put("orderAmount", orderAmount.intValue()+""); // 订单金额 //
		paramMap.put("orderNumber", request.getParameter("orderNumber")); // 商户订单号
		paramMap.put("payType", "B2C");
		paramMap.put("terType", "00"); // 网关

		paramMap.put("backEndUrl", PayConf.backEndUrl); //  通知url
		paramMap.put("frontEndUrl", PayConf.frontEndUrl); // 返回url
	
		paramMap.put("merReserved1", new String(request.getParameter("CA003").getBytes("ISO8859-1"), "UTF-8")); //商户保留字，存参保人姓名
		Model user = (Model) request.getSession().getAttribute("user");
		paramMap.put("merReserved2", user.getString("AA001")); //商户保留字，存用户ID
		paramMap.put("merReserved3", (String)request.getSession().getAttribute("orderWriteCA006")); //商户保留字，存用户ID
		paramMap.put("gateWay", PayConf.PAY_VERSION); // 网关
		
		// 定义接口参数
        String[] paramKeys = new String[]{"version", "charset", "signMethod", "payType", "transType", //
                "merId", "backEndUrl", "frontEndUrl", "orderTime", "orderNumber", "orderAmount", "orderCurrency", //
                "defaultBankNumber", "customerIp", "merReserved1", "merReserved2", "merReserved3", //
                "gateWay", "terType", "agentAmount", "orderDesc", "payPerson", "idType", "certifId", "openid"};
		Map<String, String> paramMap22 = Maps.newHashMap();
		
        for (String key : paramKeys) {
        	paramMap22.put(key, paramMap.get(key));
        }
        
        paramMap22 = Maps.filterEntries(paramMap22, new Predicate<Map.Entry<String, String>>() {
            @Override
            public boolean apply(Map.Entry<String, String> entry) {
                return StringUtils.isNotBlank(entry.getValue());
            }
        });

        //生成签名
        String sign = AppUtils.signBeforePost(paramMap22, PayConf.SIGNKEY_ZG, PayConf.CHARSET);
//        String sign = AppUtils.signBeforePost(paramMap, reqMap.get("signKey"), charset);
        System.out.println("向清算平台发送支付请求:" + paramMap22.toString());
        System.out.println("原始签名：" + sign);

        //构造请求数据表单, 过滤掉为空的值，签名时也过滤
        StringBuilder builder = new StringBuilder();
        builder.append("\r\n<script language=\"javascript\">window.onload=function(){document.payform.submit();}</script>\r\n");
        builder.append("\r\n<form id='payform' name='payform' action='" + PayConf.JSPT_PAY_URL + "' method='POST'>\r\n");
        for (String item : paramKeys) {
            String value = paramMap22.get(item);
            if (StringUtils.isNotBlank(value)) {
                builder.append("\t<input type='hidden' name='" + item + "' value='" + paramMap22.get(item) + "' />\r\n");
            }
        }
        builder.append("\t<input type='hidden' name='sign' value='" + sign + "' />\r\n");
        builder.append("</form>\r\n");


        response.setContentType("text/html;charset=" + PayConf.CHARSET);
        response.setCharacterEncoding(PayConf.CHARSET);
        try {
        	response.getWriter().write(builder.toString().replace('\'', '"'));
        } catch (IOException e) {
            System.out.println("支付失败");
        }
	}

	
	public static void main(String[] args) {
		try {
			URL url = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");
	        URLConnection con = url.openConnection();
	        con.setDoOutput(true);
	        con.setRequestProperty("Pragma:", "no-cache");
	        con.setRequestProperty("Cache-Control", "no-cache");
	        con.setRequestProperty("Content-Type", "text/xml");
	
	        OutputStreamWriter out = new OutputStreamWriter(con
	                .getOutputStream());    
	        Map<String, String[]> paramsMap = new HashMap<String, String[]>();
	        StringBuilder sb = new StringBuilder();
	        sb.append("<xml>");
	        sb.append("    <appid>wx2421b1c4370ec43b</appid>");		//应用ID
	        paramsMap.put("appid", new String[] { "wx2421b1c4370ec43b" });
	        sb.append("    <attach>test</attach>");				//附加数据
	        paramsMap.put("attach", new String[] { "test" });
	        sb.append("    <body>test</body>");				//商品描述
	        paramsMap.put("body", new String[] { "test" });
	        sb.append("    <mch_id>10000100</mch_id>");				//商户号
	        paramsMap.put("mch_id", new String[] { "10000100" });
	        sb.append("    <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>");		//随机字符串
	        paramsMap.put("nonce_str", new String[] { "1add1a30ac87aa2db72f57a2375d8fec" });
	        sb.append("    <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>");		//通知地址
	        paramsMap.put("notify_url", new String[] { "http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php" });
	        sb.append("    <out_trade_no>123456</out_trade_no>");			//商户订单号
	        paramsMap.put("out_trade_no", new String[] { "123456" });
	        sb.append("    <spbill_create_ip>10.189.139.32</spbill_create_ip>");		//终端IP
	        paramsMap.put("spbill_create_ip", new String[] { "10.189.139.32" });
	        //将金额转为分
//	        String orderNum = Double.parseDouble(request.getParameter("orderNumber"))*100 + "";
//	        String money = "";
//	        if (orderNum.contains(".")) {
//				money = orderNum.split(".")[0];
//			} else {
//				money = orderNum;
//			}
	        sb.append("    <total_fee>1</total_fee>");		//总金额
	        paramsMap.put("total_fee", new String[] { "1" });
	        sb.append("    <trade_type>APP</trade_type>");		//支付类型
	        paramsMap.put("trade_type", new String[] { "APP" });
	        String sign = EncryptionUtils.makeSignature(paramsMap, "pansky");
	        System.out.println(sign);
	        sb.append("    <sign>"+sign+"</sign>");		//签名
	        sb.append("</xml>");
	        String xmlInfo = sb.toString();
	        out.write(new String(xmlInfo.getBytes("ISO-8859-1")));
	        out.flush();
	        out.close();
	        BufferedReader br = new BufferedReader(new InputStreamReader(con
	                .getInputStream()));
	        String line = "";
	        String result = "";
	        for (line = br.readLine(); line != null; line = br.readLine()) {
	            result = result + line;
	        }
	        String return_code = result.split("<return_code>")[1].split("</return_code>")[0];
	        System.out.println(result);
	        boolean boo = return_code.contains("SUCCESS");
	        if (boo) {
				//下单成功
	        	
			} else {
				//下单失败
				System.out.println(result);
			}
		} catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
}
